package com.yj.auto.core.jfinal.context;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.core.ActionReporter;
import com.jfinal.ext.handler.ContextPathHandler;
import com.jfinal.ext.handler.UrlSkipHandler;
import com.jfinal.ext.interceptor.SessionInViewInterceptor;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.log.Log;
import com.jfinal.log.Log4jLogFactory;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory;
import com.jfinal.plugin.activerecord.SqlReporter;
import com.jfinal.plugin.activerecord.tx.TxByMethodRegex;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.druid.DruidStatViewHandler;
import com.jfinal.plugin.druid.IDruidStatViewAuth;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.template.Engine;
import com.yj.auto.core.base.online.SessionUserUtil;
import com.yj.auto.core.jfinal.directive.AuthDirective;
import com.yj.auto.core.jfinal.directive.SqlOrderByDirective;
import com.yj.auto.core.jfinal.directive.SqlParaLikeDirective;
import com.yj.auto.core.jfinal.interceptor.CacheRefreshInterceptor;
import com.yj.auto.core.jfinal.interceptor.ExceptionInterceptor;
import com.yj.auto.core.jfinal.interceptor.ServiceInterceptor;
import com.yj.auto.core.jfinal.interceptor.SessionUserInterceptor;
import com.yj.auto.core.jfinal.interceptor.ValidatorInterceptor;
import com.yj.auto.core.jfinal.plugin.QuartzPlugin;
import com.yj.auto.core.web.system.model.Schedule;
import com.yj.auto.helper.AutoHelper;
import com.yj.auto.helper.LogHelper;
import com.yj.auto.helper.ScheduleHelper;
import com.yj.auto.utils.ClassUtil;
import com.yj.auto.utils.QuartzUtil;

/**
 * API引导式配置
 */
public class AutoConfig extends JFinalConfig {
	private static final Log logger = Log.getLog(JFinalConfig.class);

	public void configConstant(Constants me) {
		me.setLogFactory(new Log4jLogFactory());
		me.setEncoding(com.yj.auto.Constants.SYS_ENCODING);
		me.setDevMode(com.yj.auto.Constants.SYS_DEV_MODE);
		me.setBaseUploadPath(com.yj.auto.Constants.SYS_UPLOAD_ROOT);
		me.setBaseDownloadPath(com.yj.auto.Constants.SYS_DOWNLOAD_ROOT);
		me.setError401View(com.yj.auto.Constants.PAGE_401);
		me.setError403View(com.yj.auto.Constants.PAGE_403);
		me.setError404View(com.yj.auto.Constants.PAGE_404);
		me.setError500View(com.yj.auto.Constants.PAGE_500);
		// SqlReporter.setLog(me.getDevMode());// 开启日志
	}

	/**
	 * 配置路由
	 */
	public void configRoute(Routes me) {
		me.setBaseViewPath(com.yj.auto.Constants.SYS_VIEW_ROOT);
		me.add(new AutoRoutesConfig());
	}

	/**
	 * 配置插件
	 */
	public void configPlugin(Plugins me) {
		// 配置数据库连接池插件
		DruidPlugin druidPlugin = getDruidPlugin();
		me.add(druidPlugin);
		// 配置ActiveRecord插件
		ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
		arp.getEngine().addDirective("like", new SqlParaLikeDirective());
		arp.getEngine().addDirective("order", new SqlOrderByDirective());
		arp.setBaseSqlTemplatePath(ClassUtil.getPathByClassPath("sql"));
		arp.addSqlTemplate("auto.sql");
		// model字段的大小写设置：false=大写, true=小写, 空是区分大小写
		arp.setContainerFactory(new CaseInsensitiveContainerFactory(true));

		arp.setDevMode(com.yj.auto.Constants.SYS_DEV_MODE);
		// arp.setShowSql(arp.getDevMode());
		me.add(arp);

		new AutoModelConfig(arp);// 自动扫描model

		me.add(new EhCachePlugin(ClassUtil.getPathByClassPath(com.yj.auto.Constants.CONF_EHCACHE)));// 缓存

		me.add(new AutoServiceConfig());// ServicePlugin Service注解实例化加载"

		me.add(new QuartzPlugin());// 任务配置
	}

	private DruidPlugin getDruidPlugin() {
		Prop p = PropKit.use(com.yj.auto.Constants.CONF_JDBC);
		DruidPlugin druidPlugin = null;
		if (com.yj.auto.Constants.SYS_DEV_MODE) {
			druidPlugin = new DruidPlugin(p.get("jdbc.url.dev"), p.get("jdbc.user"), p.get("jdbc.password"), p.get("jdbc.driver.dev"));
		} else {
			druidPlugin = new DruidPlugin(p.get("jdbc.url"), p.get("jdbc.user"), p.get("jdbc.password"));
		}
		druidPlugin.setFilters("stat,wall");
		// druidPlugin.addFilter(new Slf4jLogFilter());
		druidPlugin.setLogAbandoned(true);
		return druidPlugin;
	}

	@Override
	public void configHandler(Handlers me) {
		// 根目录获取
		me.add(new ContextPathHandler(com.yj.auto.Constants.SYS_CONTEXT_PATH));

		me.add(new UrlSkipHandler("/log4j.hml", true));

		// druid监控页面展示
		me.add(new DruidStatViewHandler("/druid", new IDruidStatViewAuth() {
			public boolean isPermitted(HttpServletRequest request) {
				return SessionUserUtil.isSuperUser(request);//// 暂时把查看权限给超级用户
			}
		}));

	}

	/**
	 * 配置全局拦截器
	 */
	public void configInterceptor(Interceptors me) {

		me.addGlobalActionInterceptor(new ExceptionInterceptor());// 统一异常处理

		me.addGlobalActionInterceptor(new SessionInViewInterceptor());// Session参数传递

		// 事务
		me.addGlobalActionInterceptor(new TxByMethodRegex("(.*save.*|.*update.*|.*delete.*)"));
		// Service注入
		me.addGlobalActionInterceptor(new ServiceInterceptor());
		// 用户是否已登录
		me.addGlobalActionInterceptor(new SessionUserInterceptor("(/assets/.*|/index.*|/captcha.*|/login.*|/logout.*|/feedback/add)"));
		// 验证拦截器
		me.addGlobalActionInterceptor(ValidatorInterceptor.me());
		// 刷新缓存
		me.addGlobalServiceInterceptor(new CacheRefreshInterceptor("(.*save.*|.*update.*|.*delete.*)"));

		// 国际化资源
		// me.add(new I18nInterceptor());

	}

	/**
	 * 配置模板
	 */
	public void configEngine(Engine me) {
		me.addDirective("auth", new AuthDirective());
		me.addSharedObject("SYS_NAME", com.yj.auto.Constants.SYS_NAME);
		me.addSharedObject("SYS_ASSET_VERSION", com.yj.auto.Constants.SYS_ASSET_VERSION);
		me.addSharedObject("SYS_COPYRIGHT", com.yj.auto.Constants.SYS_COPYRIGHT);
		me.addSharedObject("SYS_INDEX_URI", com.yj.auto.Constants.SYS_INDEX_URI);
		me.addSharedFunction("views/common/_layout.html");
		me.addSharedFunction("views/common/_auth_btn.html");
		me.addSharedFunction("views/common/_dict.html");
	}

	/**
	 * 系统加载完成后的初始化
	 */
	@Override
	public void afterJFinalStart() {
		super.afterJFinalStart();

		// 添加任务
		try {
			ScheduleHelper.loadSchedule();
		} catch (Exception e) {
			logger.error("定时任务加载异常", e);
		}
		LogHelper.getLoginLogService().updateLogout();
		System.out.println("############系统启动完成##########");
	}

	@Override
	public void beforeJFinalStop() {
		super.afterJFinalStart();
		System.out.println("############系统停止完成##########");
	}

}
